package com.xbongbong.paas.help.service.impl;

import com.alibaba.fastjson.JSON;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.ext.ConditionsEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.dto.SearchDataInConditionDTO;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.enums.ConditionEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.LinkInfoPojo;
import com.xbongbong.paas.help.base.BaseLinkBoolQueryBuilderService;
import com.xbongbong.paas.help.service.BoolQueryBuilderService;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.pojo.dto.LinkDataListDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.help.SaasListHelp;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * @author: wufeng
 * @date: 2018/11/7 20:00
 * @desrcption: 关联数据
 */
@Component
public class LinkDataBoolQueryBuilderServiceImpl extends BaseLinkBoolQueryBuilderService implements BoolQueryBuilderService<LinkDataListDTO>  {

    private static  final Logger LOG = LoggerFactory.getLogger(LinkDataBoolQueryBuilderServiceImpl.class);

    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private SaasListHelp saasListHelp;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private UserModel userModel;
    @Resource
    private IndexTypeModel indexTypeModel;

    @Override
    public Boolean getBoolQueryBuilder(BoolQueryBuilder boolQueryBuilder, LinkDataListDTO linkDataListDTO) throws XbbException{
        try {
            String corpid = linkDataListDTO.getCorpid();
            // 搜索当前表单字段信息
            List<FieldAttrEntity> explainList = linkDataListDTO.getPreviewFieldList();
            Map<String, FieldAttrEntity> explainMap;
            if (CollectionsUtil.isEmpty(explainList)) {
                PaasFormExplainEntity paasFormExplainEntity = new PaasFormExplainEntity();
                if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkDataListDTO.getBusinessType())) {
                    WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(linkDataListDTO.getFormId(), corpid);
                    BeanUtil.copyProperties(workOrderExplainEntity, paasFormExplainEntity);
                } else {
                    paasFormExplainEntity = paasFormExplainModel.getByFormId(linkDataListDTO.getFormId(), corpid);
                }
                if(paasFormExplainEntity == null) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
                }
                explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
            } else {
                explainMap = ExplainUtil.getExplainMap(JSON.toJSONString(explainList), null);
            }

            // 存储当前字段的表单字段详情并放入容器
            LinkInfoPojo linkInfoPojo = linkDataListDTO.getLinkInfo();
            if(Objects.isNull(linkInfoPojo) || linkInfoPojo.getLinkFormId() == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.NOT_SET_LINK_FORM);
            }
            // 搜索联动表单字段
            PaasFormExplainEntity relyExplain = new PaasFormExplainEntity();
            if (Objects.equals(XbbRefTypeEnum.WORK_ORDER.getCode(), linkInfoPojo.getLinkBusinessType())) {
                WorkOrderExplainEntity workOrderExplainEntity = workOrderExplainModel.getByFormId(linkInfoPojo.getLinkFormId(), corpid);
                BeanUtil.copyProperties(workOrderExplainEntity, relyExplain);
            } else {
                relyExplain = paasFormExplainModel.getByFormId(linkInfoPojo.getLinkFormId(), corpid);
            }
            if(relyExplain == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_EXPLAIN_NOT_EXIST);
            }
            // 联动表单字段容器
            Map<String, FieldAttrEntity> relyExplainMap = ExplainUtil.getExplainMap(relyExplain.getExplains(), null);
            // 增加一个id字段
            FieldAttrEntity dataIdFieldAttrEntity = new FieldAttrEntity();
            dataIdFieldAttrEntity.setAttr(FieldTypeEnum.DATAID.getAlias());
            dataIdFieldAttrEntity.setAttrName(FieldTypeEnum.DATAID.getAlias());
            dataIdFieldAttrEntity.setFieldType(FieldTypeEnum.DATAID.getType());
            relyExplainMap.put(FieldTypeEnum.DATAID.getAlias(), dataIdFieldAttrEntity);
            // 获取值容器
            Map<String, Object> valueMap = getValueMap(explainMap, linkDataListDTO.getValue(), linkDataListDTO.getLinkInfo(), corpid);
            // 获取对应的es条件
            Boolean result = returnBoolQueryBuilder(relyExplainMap, explainMap, valueMap, linkInfoPojo.getCondition(), boolQueryBuilder, linkDataListDTO.getLinkInfo(), corpid);
            if (!result) {
                return result;
            }
            //解析查询条件
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery("formId", linkInfoPojo.getLinkFormId()));
            boolQueryBuilder.filter(termQuery("del", 0));
            // 获取权限内的数据
            SearchDataInConditionDTO searchDataInConditionDTO = new SearchDataInConditionDTO();
            BeanUtil.copyProperties(linkDataListDTO, searchDataInConditionDTO);
            searchDataInConditionDTO.setBusinessType(linkInfoPojo.getLinkBusinessType());
            searchDataInConditionDTO.setSubBusinessType(linkInfoPojo.getLinkBusinessType());
            searchDataInConditionDTO.setSaasMark(linkInfoPojo.getLinkSaasMark());
            searchDataInConditionDTO.setFormId(linkInfoPojo.getLinkFormId());
            searchDataInConditionDTO.setDefaultGroup(1);
            searchDataInConditionDTO.setListGroupId(ListGroupEnum.ALL.getCode().longValue());
            if(!linkDataListDTO.getLoginUser().isAdminOrBoss() && Objects.equals(linkInfoPojo.getLinkBusinessType(),XbbRefTypeEnum.COMMUNICATE_PLAN.getCode())){
                UserEntity userEntity = userModel.getByKey(linkDataListDTO.getUserId(),corpid);
                Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), null);
                List<String> userIdList = userModel.getSubIdListByDataPermission(dataPermission, userEntity.getUserId(), userEntity.getCorpid(), BasicConstant.ZERO,false);
                Set<String> userSet = new LinkedHashSet<>(userIdList);
                ConditionsEntityExt teamConditionsEntityExt = new ConditionsEntityExt(FieldTypeEnum.TEAM_USER.getAlias(), null, FieldTypeEnum.TEAM_USER.getType(), ConditionEnum.IN.getSymbol(), new ArrayList<>(userSet));
                searchDataInConditionDTO.getConditionsList().add(teamConditionsEntityExt);
            }
            saasListHelp.packageSearchDataCondition(searchDataInConditionDTO);

            EsUtil.parseCondition(boolQueryBuilder,searchDataInConditionDTO.getConditionsList(),"",searchDataInConditionDTO.getCorpid(),searchDataInConditionDTO.getBusinessType());

            BoolQueryBuilder boolQuery = boolQuery();
            EsUtil.parseShouldCondition(boolQuery,searchDataInConditionDTO.getShouldConditionsList(),"",searchDataInConditionDTO.getCorpid(),searchDataInConditionDTO.getBusinessType());
            boolQueryBuilder.filter(boolQuery);
            // 共享权限封装
            EsUtil.parseSharePermissionCondition(boolQueryBuilder, searchDataInConditionDTO.getSharePermission(), searchDataInConditionDTO.getCorpid(), searchDataInConditionDTO.getBusinessType(), false);

            if (Objects.equals(linkInfoPojo.getLinkSaasMark(), SaasMarkEnum.SAAS.getCode())) {
                // TODO 关联数据-产品先查出父产品，再根据父产品id查出子产品
                if (Objects.equals(linkInfoPojo.getLinkBusinessType(), XbbRefTypeEnum.PRODUCT.getCode())) {
                    boolQueryBuilder.filter(termQuery(ProductEnum.getEsAttr4Keyword(ProductEnum.PARENT_ID), 0));
                } else if (Objects.equals(linkInfoPojo.getLinkBusinessType(), XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode())) {
                    // 项目日志类型（0：跟进记录）
                    boolQueryBuilder.filter(termQuery("logType", 0));
                }
            }
        }catch (XbbException e) {
            throw e;
        } catch (Exception e){
            LOG.error("linkSearchBoolQueryBuilder获取es搜索条件失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return true;
    }
}
